#===============================================================================
#
#          FILE: operational_laws.rb
#
#         USAGE: require_relative operational_laws.rb
#
#   DESCRIPTION: Ruby implementation of operational laws
#
#       OPTIONS: ---
#  REQUIREMENTS: ruby 1.9.3
#          BUGS: ---
#         NOTES: ---
#        AUTHORS: Marcelo Bassani de Freitas - mbf2@cin.ufpe.br
#                 Tarcisio Coutinho - tcs5@cin.ufpe.br
#       CREATED: 05/20/2013 12:53:21 PM BRT
#      REVISION: 0.0.1
#===============================================================================

# Ui = Xi * Si
# Ui = Xi * Di
# Ui = Xi * Si * Vi
def utilization_law(*args)
  if args.length == 2
    simple_utilization_law(args[0], args[1])
  elsif args.length == 3
    derived_utilization_law(args[0], args[1], args[2])
  end
end

# Ui = Xi * Si
def simple_utilization_law(d_throughput, d_service_time)
  d_throughput * d_service_time
end

# Ui = Xi * Di
# Di = Si * Vi
# Ui = X * Si * Vi
def derived_utilization_law(s_throughput, d_service_time, d_visits_rate)
  s_throughput * d_service_time * d_visits_rate
end

# Xi = X * Vi
def forced_flow_law(s_throughput, d_visits_rate)
  s_throughput * d_visits_rate
end

# Qi = Xi * Ri
def littles_law(d_throughput, d_response_time)
  d_throughput * d_response_time
end

# Q = R * X
# Q = Q1 + Q2 + .. + Qn
# R = sum(Vi * Ri)
def gerenal_response_time_law(d_response_times={}, d_visits_rates={})
  s_reponse_time = 0
  d_response_times.keys.each { |i| s_reponse_time += d_response_times[i] * d_visits_rates[i] }
  s_reponse_time
end

# R = N/X - Z
def interactive_response_time_law(s_jobs, s_throughput, think_time)
  (s_jobs / s_throughput) - think_time
end

# R >= max(D, N * Dmax -Z)
def response_time_asymptotic_bounds(d_visits_rates={}, s_jobs, think_time)
  temp = []
  service_demands = 0
  max_service_demand = d_visits_rates.values.max
  d_visits_rates.values.each { |x| service_demands += x}

  temp << service_demands
  temp << (s_jobs * max_service_demand) - think_time
  temp.max
end

# X <= (1/Dmax, N / (D + Z))
def throughput_time_asymptotic_bounds(d_visits_rates={}, s_jobs, think_time)
  temp = []
  service_demands = 0
  max_service_demand = d_visits_rates.values.max
  d_visits_rates.values.each { |x| service_demands += x}

  temp << service_demands
  temp << (s_jobs/(service_demands + think_time))
  temp.min
end
